package com.xshiwu.es.test;

import org.apache.http.HttpHost;
import org.elasticsearch.action.search.SearchRequest;
import org.elasticsearch.action.search.SearchResponse;
import org.elasticsearch.client.RequestOptions;
import org.elasticsearch.client.RestClient;
import org.elasticsearch.client.RestHighLevelClient;
import org.elasticsearch.common.unit.Fuzziness;
import org.elasticsearch.index.query.*;
import org.elasticsearch.search.SearchHit;
import org.elasticsearch.search.SearchHits;
import org.elasticsearch.search.aggregations.AggregationBuilders;
import org.elasticsearch.search.aggregations.bucket.terms.TermsAggregationBuilder;
import org.elasticsearch.search.builder.SearchSourceBuilder;
import org.elasticsearch.search.fetch.subphase.highlight.HighlightBuilder;

import java.io.IOException;

/**
 * @Project: es
 * @Author: Sunday
 * @Create: 2021-09-03 17:02
 **/
public class EsTestDocQuery {
    public static void main(String[] args) throws Exception {
        // queryAll();
        // 条件查询
        // ConditionQuery();
        // 分页查询
        // pageQuery();
        // 组合查询
        // combineQuery();
        // 范围查询
        // rangeQuery();
        // 模糊查询
        // fuzzyQuery();
        // 高亮查询
        // highlightQuery();
        // 聚合查询
        aggregateQuery();
    }

    // 聚合查询
    private static void aggregateQuery() throws IOException {
        // 创建客户端对象
        RestHighLevelClient client = new RestHighLevelClient(
                RestClient.builder(new HttpHost("localhost", 9200, "http")));

        // 1. 查询索引中的全部数据
        SearchRequest request = new SearchRequest();
        request.indices("user");

        SearchSourceBuilder builder = new SearchSourceBuilder();

        TermsAggregationBuilder aggregationBuilder = AggregationBuilders.terms("ageGroup").field("age");

        builder.aggregation(aggregationBuilder);

        request.source(builder);

        SearchResponse response = client.search(request, RequestOptions.DEFAULT);
        System.out.println(response);
        SearchHits hits = response.getHits();
        System.out.println(response.getTook());
        System.out.println(hits.getTotalHits());
        for (SearchHit hit : hits) {
            System.out.println(hit.getSourceAsString());
        }

        // 关闭客户端连接
        client.close();
    }

    private static void highlightQuery() throws IOException {
        // 创建客户端对象
        RestHighLevelClient client = new RestHighLevelClient(
                RestClient.builder(new HttpHost("localhost", 9200, "http")));

        // 1. 查询索引中的全部数据
        SearchRequest request = new SearchRequest();
        request.indices("user");

        SearchSourceBuilder builder = new SearchSourceBuilder();
        TermQueryBuilder termQueryBuilder = QueryBuilders.termQuery("name", "zhangsan");

        HighlightBuilder highlighter = new HighlightBuilder();
        highlighter.preTags("<font color='red'>");
        highlighter.postTags("</font>");
        highlighter.field("name");

        builder.highlighter(highlighter);

        builder.query(termQueryBuilder);

        request.source(builder);

        SearchResponse response = client.search(request, RequestOptions.DEFAULT);
        System.out.println(response);
        SearchHits hits = response.getHits();
        System.out.println(response.getTook());
        System.out.println(hits.getTotalHits());
        for (SearchHit hit : hits) {
            System.out.println(hit.getSourceAsString());
        }

        // 关闭客户端连接
        client.close();
    }

    /**
     * 模糊查询
     */
    private static void fuzzyQuery() throws IOException {
        // 创建客户端对象
        RestHighLevelClient client = new RestHighLevelClient(
                RestClient.builder(new HttpHost("localhost", 9200, "http")));

        // 1. 查询索引中的全部数据
        SearchRequest request = new SearchRequest();
        request.indices("user");

        SearchSourceBuilder builder = new SearchSourceBuilder();
        FuzzyQueryBuilder fuzzyQuery = QueryBuilders.fuzzyQuery("name", "zhangsa");
        fuzzyQuery.fuzziness(Fuzziness.ONE);
        builder.query(fuzzyQuery);

        request.source(builder);

        SearchResponse response = client.search(request, RequestOptions.DEFAULT);
        SearchHits hits = response.getHits();
        System.out.println(response.getTook());
        System.out.println(hits.getTotalHits());
        for (SearchHit hit : hits) {
            System.out.println(hit.getSourceAsString());
        }

        // 关闭客户端连接
        client.close();
    }

    /**
     * 范围查询
     */
    private static void rangeQuery() throws IOException {
        // 创建客户端对象
        RestHighLevelClient client = new RestHighLevelClient(
                RestClient.builder(new HttpHost("localhost", 9200, "http")));

        // 1. 查询索引中的全部数据
        SearchRequest request = new SearchRequest();
        // 指定索引
        request.indices("user");

        // 用于创建搜索查询的实用程序类
        RangeQueryBuilder queryBuilder = QueryBuilders.rangeQuery("age");

        // 年龄在13和18之间
        queryBuilder.gte(13);
        queryBuilder.lte(18);

        SearchSourceBuilder builder = new SearchSourceBuilder().query(queryBuilder);
        request.source(builder);

        SearchResponse response = client.search(request, RequestOptions.DEFAULT);
        SearchHits hits = response.getHits();
        System.out.println(response.getTook());
        System.out.println(hits.getTotalHits());
        for (SearchHit hit : hits) {
            System.out.println(hit.getSourceAsString());
        }

        // 关闭客户端连接
        client.close();
    }

    private static void combineQuery() throws IOException {
        // 创建客户端对象
        RestHighLevelClient client = new RestHighLevelClient(
                RestClient.builder(new HttpHost("localhost", 9200, "http")));

        // 1. 查询索引中的全部数据
        SearchRequest request = new SearchRequest();
        // 指定索引
        request.indices("user");

        // 用于创建搜索查询的实用程序类
        BoolQueryBuilder boolQueryBuilder = QueryBuilders.boolQuery();
        // boolQueryBuilder.must(QueryBuilders.matchQuery("age", 13));
        // boolQueryBuilder.must(QueryBuilders.matchQuery("sex", "女"));
        // boolQueryBuilder.mustNot(QueryBuilders.matchQuery("sex", "女"));

        // 年龄是13或者是18
        boolQueryBuilder.should(QueryBuilders.matchQuery("age", 13));
        boolQueryBuilder.should(QueryBuilders.matchQuery("age", 18));

        SearchSourceBuilder builder = new SearchSourceBuilder().query(boolQueryBuilder);
        request.source(builder);

        SearchResponse response = client.search(request, RequestOptions.DEFAULT);
        SearchHits hits = response.getHits();
        System.out.println(response.getTook());
        System.out.println(hits.getTotalHits());
        for (SearchHit hit : hits) {
            System.out.println(hit.getSourceAsString());
        }

        // 关闭客户端连接
        client.close();
    }

    private static void pageQuery() throws IOException {
        // 创建客户端对象
        RestHighLevelClient client = new RestHighLevelClient(
                RestClient.builder(new HttpHost("localhost", 9200, "http")));

        // 1. 查询索引中的全部数据
        SearchRequest request = new SearchRequest();
        // 指定索引
        request.indices("user");

        // 用于创建搜索查询的实用程序类
        SearchSourceBuilder builder = new SearchSourceBuilder().query(QueryBuilders.matchAllQuery());
        // (当前页码-1) * 煤业显示的数据量
//        builder.sort("age", SortOrder.DESC);
//        builder.from(2);
//        builder.size(2);
        // 排除的数据
        String[] excludes = {};
        // 包含的数据
        String[] includes = {"name"};
        builder.fetchSource(includes, excludes);
        request.source(builder);

        SearchResponse response = client.search(request, RequestOptions.DEFAULT);
        SearchHits hits = response.getHits();
        System.out.println(response.getTook());
        System.out.println(hits.getTotalHits());
        for (SearchHit hit : hits) {
            System.out.println(hit.getSourceAsString());
        }

        // 关闭客户端连接
        client.close();
    }

    private static void queryAll() throws IOException {
        // 创建客户端对象
        RestHighLevelClient client = new RestHighLevelClient(
                RestClient.builder(new HttpHost("localhost", 9200, "http")));

        // 1. 查询索引中的全部数据
        SearchRequest request = new SearchRequest();
        // 指定索引
        request.indices("user");

        // 用于创建搜索查询的实用程序类
        request.source(new SearchSourceBuilder().query(QueryBuilders.matchAllQuery()));

        SearchResponse response = client.search(request, RequestOptions.DEFAULT);
        SearchHits hits = response.getHits();
        System.out.println(response.getTook());
        System.out.println(hits.getTotalHits());
        for (SearchHit hit : hits) {
            System.out.println(hit.getSourceAsString());
        }

        // 关闭客户端连接
        client.close();
    }

    private static void ConditionQuery() throws IOException {
        // 创建客户端对象
        RestHighLevelClient client = new RestHighLevelClient(
                RestClient.builder(new HttpHost("localhost", 9200, "http")));

        // 1. 查询索引中的全部数据
        SearchRequest request = new SearchRequest();
        // 指定索引
        request.indices("user");

        // 用于创建搜索查询的实用程序类
        request.source(new SearchSourceBuilder().query(QueryBuilders.termQuery("age", "18")));

        SearchResponse response = client.search(request, RequestOptions.DEFAULT);
        SearchHits hits = response.getHits();
        System.out.println(response.getTook());
        System.out.println(hits.getTotalHits());
        for (SearchHit hit : hits) {
            System.out.println(hit.getSourceAsString());
        }

        // 关闭客户端连接
        client.close();
    }
}
